import {boardSize} from "./Data.js";
//规则
// 计算棋子的可能移动位置
function calculatePossibleMoves(type, color, x, y, PiecesData) {
    // 根据棋子的类型和颜色计算可能的移动位置

    // 这里可以根据棋子的类型和颜色计算可能的移动位置
    if (type === '车') {
        return calculatePossibleMovesForRook(color, x, y, PiecesData);
    }
    if (type === '马') {
        // 马的移动规则
        return calculatePossibleMovesForHorse(color, x, y, PiecesData);
    }
    if (type === '炮') {
        // 炮的移动规则
        return calculatePossibleMovesForGun(color, x, y, PiecesData);
    }
    if (type === '兵' || type === '卒') {
        // 卒或兵的移动规则
        return calculatePossibleMovesForSoldier(color, x, y, PiecesData);

    }
    if (type === '相' || type === '象') {
        // 象或相的移动规则
        return calculatePossibleMovesForBishop(color, x, y, PiecesData);

    }
    if (type === '仕' || type === '士') {
        // 士或仕的移动规则
        return calculatePossibleMovesForChevalier(color, x, y, PiecesData);
    }
    if (type === '帅' || type === '将') {
        // 帅或将的移动规则
        return calculatePossibleMovesForKing(color, x, y, PiecesData);
    }

}

//isPieceAt(x, y)：检查指定位置是否有棋子。
// true ：有棋子
function isPieceAt(x, y, PiecesData) {

    //some 的方法 测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到提供的函数返回 true 的元素，则返回 true;否则返回 false。它不会修改数组。

    return PiecesData.some(piece => piece.x === x && piece.y === y);
}

//isValidMove(x, y)：检查移动是否在棋盘范围内。
function isValidMove(x, y) {
    return x >= 0 && x < boardSize.cellWidthNumber && y >= 0 && y < boardSize.cellHeightNumber;
}

//isMyPiece 是否为我方棋子
// true:是我方棋子
function isMyPiece(color, x, y, PiecesData) {
    return PiecesData.some(piece => piece.color === color && piece.x === x && piece.y === y);
}


//马走“日”字，可以跳过其他棋子。
function calculatePossibleMovesForHorse(color, x, y, PiecesData) {
    const moves = [];
    const elephantMoves = [
        {x: x + 1, x1: x, y: y - 2, y1: y - 1},
        {x: x + 2, x1: x + 1, y: y - 1, y1: y},
        {x: x + 2, x1: x + 1, y: y + 1, y1: y},
        {x: x + 1, x1: x, y: y + 2, y1: y + 1},
        {x: x - 1, x1: x, y: y + 2, y1: y + 1},
        {x: x - 2, x1: x - 1, y: y + 1, y1: y},
        {x: x - 2, x1: x - 1, y: y - 1, y1: y},
        {x: x - 1, x1: x, y: y - 2, y1: y - 1},
    ];

    //10点
    elephantMoves.forEach(move => {
        if (isValidMove(move.x, move.y) && !isPieceAt(move.x1, move.y1, PiecesData) &&
            (!isMyPiece(color, move.x, move.y, PiecesData) || !isPieceAt(move.x, move.y, PiecesData))) {
            moves.push({
                x: move.x,
                y: move.y
            });
        }
    })

    return moves;
}

//车可以沿着横向和纵向无限移动，直到遇到其他棋子或棋盘边界。
function calculatePossibleMovesForRook(color, x, y, PiecesData) {
    const moves = [];
    //判断规则
    let Judging = function (x1, y1) {
        // 有棋子且不是我方
        if (isPieceAt(x1, y1, PiecesData) && !isMyPiece(color, x1, y1, PiecesData)) {
            moves.push({x: x1, y: y1});
            return false;
        }
        // 有棋子是我方
        if (isPieceAt(x1, y1, PiecesData)) {
            return false;
        }
        // 无棋子
        moves.push({x: x1, y: y1});
        return true;
    }

    const elephantMoves = [
        {i: x - 1, i1: x + 1, iMax1: boardSize.cellWidthNumber, XYisPieceAt: true},
        {i: y - 1, i1: y + 1, iMax1: boardSize.cellHeightNumber, XYisPieceAt: false},
    ];
    elephantMoves.forEach(move => {
        for (let i = move.i; i >= 0; i--) {
            if (move.XYisPieceAt) {
                if (!Judging(i, y)) {
                    break;
                }
            } else {
                if (!Judging(x, i)) {
                    break;
                }
            }
        }
        for (let i = move.i1; i < move.iMax1; i++) {
            if (move.XYisPieceAt) {
                if (!Judging(i, y)) {
                    break;
                }
            } else {
                if (!Judging(x, i)) {
                    break;
                }
            }
        }
    })
    return moves;
}

//象走“田”字，不能过河。
function calculatePossibleMovesForBishop(color, x, y, PiecesData) {
    const elephantMoves = [
        {x: x + 2, y: y + 2, x1: x + 1, y1: y + 1},
        {x: x + 2, y: y - 2, x1: x + 1, y1: y - 1},
        {x: x - 2, y: y + 2, x1: x - 1, y1: y + 1},
        {x: x - 2, y: y - 2, x1: x - 1, y1: y - 1}
    ];
    const moves = [];

    elephantMoves.forEach(move => {

        if (isValidMove(move.x, move.y) && !isPieceAt(move.x1, move.y1, PiecesData) && (!isPieceAt(move.x, move.y, PiecesData) || !isMyPiece(color, move.x, move.y, PiecesData))) {
            // 检查是否过河
            if ((color === 'black' && move.y <= 4) || (color === 'red' && move.y >= 5)) {
                moves.push(move);
            }
        }
    });

    return moves;
}

// 士只能在九宫格内斜着移动。
function calculatePossibleMovesForChevalier(color, x, y, PiecesData) {
    const moves = [];
    const advisorMoves = [
        {x: x + 1, y: y + 1},
        {x: x + 1, y: y - 1},
        {x: x - 1, y: y + 1},
        {x: x - 1, y: y - 1}
    ];
    advisorMoves.forEach(move => {
        if (isValidMove(move.x, move.y) && (!isPieceAt(move.x, move.y, PiecesData) || !isMyPiece(color, move.x, move.y, PiecesData))) {
            // 检查是否在九宫格内
            if ((move.x >= 3 && move.x <= 5) && ((color === 'black' && move.y <= 2) || (color === 'red' && move.y >= 7))) {
                moves.push(move);
            }
        }
    });
    return moves;
}

//将（帅）只能在九宫格内移动，不能过河。
function calculatePossibleMovesForKing(color, x, y, PiecesData) {
    const moves = [];
    const kingMoves = [
        {x: x + 1, y},
        {x: x - 1, y},
        {x, y: y + 1},
        {x, y: y - 1}
    ];
    kingMoves.forEach(move => {
        if (isValidMove(move.x, move.y) && (!isPieceAt(move.x, move.y, PiecesData) || !isMyPiece(color, move.x, move.y, PiecesData))) {
            // 检查是否在九宫格内
            if ((move.x >= 3 && move.x <= 5) && ((color === 'black' && move.y <= 2) || (color === 'red' && move.y >= 7))) {
                moves.push(move);
            }
        }
    });
    return moves;
}

// 炮只能在直线上移动，遇到其他棋子时可以吃掉，但不能跳过其他棋子。
function calculatePossibleMovesForGun(color, x, y, PiecesData) {
    const moves = [];

    // 炮的移动规则

    //是否有兵
    let hasPiece = false;
    for (let i = x + 1; i < boardSize.cellWidthNumber; i++) {
        if (isPieceAt(i, y, PiecesData)) {
            if (hasPiece) {
                if (!isMyPiece(color, i, y, PiecesData)) {
                    moves.push({x: i, y});
                }
                break;
            } else {
                hasPiece = true;
            }
        } else if (!hasPiece) {
            moves.push({x: i, y});
        }
    }

    hasPiece = false;
    for (let i = x - 1; i >= 0; i--) {
        if (isPieceAt(i, y, PiecesData)) {
            if (hasPiece) {
                if (!isMyPiece(color, i, y, PiecesData)) {
                    moves.push({x: i, y});
                }

                break;
            } else {
                hasPiece = true;
            }
        } else if (!hasPiece) {
            moves.push({x: i, y});
        }
    }

    hasPiece = false;
    for (let j = y + 1; j < boardSize.cellHeightNumber; j++) {
         if (isPieceAt(x, j, PiecesData)) {
            if (hasPiece) {
                if (!isMyPiece(color, x, j, PiecesData)) {
                    moves.push({x, y: j});
                }

                break;
            } else {
                hasPiece = true;
            }
        } else if (!hasPiece) {
            moves.push({x, y: j});
        }
    }

    hasPiece = false;
    for (let j = y - 1; j >= 0; j--) {
        if (isPieceAt(x, j, PiecesData)) {
            if (hasPiece) {
                if (!isMyPiece(color, x, j, PiecesData)) {
                    moves.push({x, y: j});
                }
                break;
            } else {
                hasPiece = true;
            }
        } else if (!hasPiece) {
            moves.push({x, y: j});
        }
    }

    return moves;
}

//兵/卒只能向前移动，不能向后移动。
function calculatePossibleMovesForSoldier(color, x, y, PiecesData) {
    const moves = [];
    // 兵/卒的移动规则
    const forward = color === 'black' ? 1 : -1;
    if (isValidMove(x, y + forward) && (!isPieceAt(x, y + forward, PiecesData) || !isMyPiece(color, x, y + forward, PiecesData))) {
        moves.push({x, y: y + forward});
    }
    if ((color === 'black' && y >= 5) || (color === 'red' && y <= 4)) {
        if (isValidMove(x + 1, y) && (!isPieceAt(x + 1, y, PiecesData) || !isMyPiece(color, x + 1, y, PiecesData))) {
            moves.push({x: x + 1, y});
        }
        if (isValidMove(x - 1, y) && (!isPieceAt(x - 1, y, PiecesData) || !isMyPiece(color, x - 1, y, PiecesData))) {
            moves.push({x: x - 1, y});
        }
    }
    return moves;
}

export {
    calculatePossibleMoves
};